/*
 * © Copyright 2011 Romain Marteau, Matthieu Totet
 * 
 *    This file is part of VineaToum.
 *
 *    VineaToum is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    VineaToum is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with VineaToum.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.vineatoum.utils;

/* ***************************************************************************
 * A simple Calculator by-- Bazlur Rahman
 * Level    : Intermediate.
 * Structure : Two files: Calculation Logic, GUI (subclass of JFrame)
 * Components: JButton, JTextField (right justified).
 * Containers: JFrame, a JPanels.
 * Layouts  : FlowLayout to put the buttonPanel, JTextFiled.
 * GridLayout in the Buttonpanel for the buttons.
 * Listeners : One ActionListener which is shared by all
 * numeric key buttons. 
 * Other    : Use Font to enlarge font for components.
 *
 * Authors: A. N. M. Bazlur Rahman
 * email: anm_brr@yahoo.com    

 *************************************************************************/

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Calc extends JFrame implements ActionListener {
    // Constant
    private final static Font BIGGER_FONT = new Font("monspaced", Font.PLAIN,
            20);

    private JTextField displayField; // component reference to display the
    // result
    private JPanel buttonPanel; // component reference to hold the button of the
    // calculator

    private CalculatorLogic calLogic = new CalculatorLogic(); // instance of the
    // CalculatorLogic
    // Class

    private JButton clear; // reference of clear button to clear the
    // displayFiled

    // here is some flag used different purpose
    private boolean pluz = false; // while true program perform addition
    private boolean subs = false; // while true program perform subtraction
    private boolean multiply = false; // while true program perform
    // multiplication
    private boolean divide = false; // while true program perform division
    private boolean startNumber = true; // decided to use for further
    // development. here actually no use
    // it..
    private boolean dotCheck = false;// if it is false we can put dot otherwise
    // not..

    private String firstValue, Secondvalue; // here our all operation between

    // two value. so here the two variables store the values

    // =======================================================================//
    public Calc() {
        super("Simple Calculator"); // name of the frame

        setLayout(new FlowLayout()); // I use FlowLayout in Our Frame

        // attributes of display fields
        displayField = new JTextField("", 12); // instance of the button panel
        displayField.setHorizontalAlignment(JTextField.RIGHT);
        // set the display text from right side.
        displayField.setFont(BIGGER_FONT); // set the font of the displayField
        add(displayField); // add() method is called for adding the displayField
        // in the Frame

        buttonPanel = new JPanel(); // instance of the button panel that holds
        buttonPanel.setPreferredSize(new Dimension(250, 150)); // here
        // setPreferredSize()
        // used to set
        // size of the
        // button Panel.
        // it take a
        // Dimension as
        // a parameter
        // lots of button of the calculator

        String buttonOrder = "789/456*123-0.=+"; // orientation of Button

        buttonPanel.setLayout(new GridLayout(4, 4, 10, 10)); // we use
        // GridLayout in
        // the
        // buttonPanel.
        // and there is
        // 10 pixel
        // space between
        // every button
        // and here I
        // make 4
        // columns and 4
        // rows for the
        // button
        // orientation

        // for loop is used to make the button
        for (int i = 0; i < buttonOrder.length(); i++) {
            String topKey = buttonOrder.substring(i, i + 1);// substring method
            // is called to get
            // the button name
            // from the
            // buttonOrder
            // String
            JButton button = new JButton(topKey); // / here we instantiate the
            // button with a name
            buttonPanel.add(button); // here we add the button in the
            // buttonPanel
            button.addActionListener(this); // here we add a ActionListener for
            // the button
        }

        add(buttonPanel);// at lastly we add the buttonPanel to the frame

        clear = new JButton("Clear"); // here is the instance of clear button
        clear.addActionListener(this); // add the actionListener for the clear
        // button
        add(clear); // add the clear button to the Frame

    }

    // ======================================================================//

    // here we override the actionPerformed method in the ActionListener
    // interface
    @Override
    public void actionPerformed(ActionEvent e) {
        // here is some if else condition ... if startNumber is true then we can
        // add some value in the displayField to perform our operation
        if (e.getActionCommand().endsWith("7")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "7");
            }
        } else if (e.getActionCommand().endsWith("8")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "8");
            }
        } else if (e.getActionCommand().endsWith("9")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "9");
            }
        } else if (e.getActionCommand().endsWith("4")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "4");
            }
        } else if (e.getActionCommand().endsWith("5")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "5");
            }
        } else if (e.getActionCommand().endsWith("6")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "6");
            }
        } else if (e.getActionCommand().endsWith("3")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "3");
            }
        } else if (e.getActionCommand().endsWith("2")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "2");
            }
        } else if (e.getActionCommand().endsWith("1")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "1");
            }
        } else if (e.getActionCommand().endsWith("0")) {
            if (startNumber) {
                displayField.setText(displayField.getText() + "0");
            }
        } else if (e.getActionCommand().endsWith(".")) {
            // if dotCheck boolean type is false, then we can add a dot in the
            // displayFiled otherwise not.
            // it is used to avoid multiple dot in the displayFiled
            if (dotCheck == false) {
                dotCheck = true;
                displayField.setText(displayField.getText() + ".");
            }
        } else if (e.getActionCommand().endsWith("+")) {
            // here if the actionCommand is equal to "+" then, we need to
            // perform addition .
            // so first we store the first Value to firstValue String calling
            // the getText() method and then
            // clear the display area for next value and make the pluz boolean
            // type true so that we can perform addition and make the dotCheck
            // variable false so that second value can contain dot
            firstValue = displayField.getText();
            displayField.setText("");
            pluz = true;
            subs = false;
            divide = false;
            multiply = false;
            dotCheck = false;

        } else if (e.getActionCommand().endsWith("-")) {
            // Same thing have done here as before in the addition
            firstValue = displayField.getText();
            displayField.setText("");
            subs = true;
            pluz = false;
            divide = false;
            multiply = false;
            dotCheck = false;

        } else if (e.getActionCommand().endsWith("*")) {
            // Same thing have done here as before in the addition
            firstValue = displayField.getText();
            displayField.setText("");
            multiply = true;
            pluz = false;
            subs = false;
            divide = false;
            dotCheck = false;

        } else if (e.getActionCommand().endsWith("/")) {
            // Same thing have done here as before in the addition
            firstValue = displayField.getText();
            displayField.setText("");
            divide = true;
            dotCheck = false;
            pluz = false;
            subs = false;
            multiply = false;
        } else if (e.getActionCommand().endsWith("=")) {
            // here we store the second value in the SecondValue String calling
            // the getText() method
            Secondvalue = displayField.getText();

            // here I've done some complex operation of java
            // if pluz flag is true then, we fist call the add() method from the
            // CalculatorLogig class
            // the method takes two variable that is double. but our value is
            // String type. so we need to parse it in double.
            // we call the method stringToDouble() from my CalculatorLogig
            // class. it takes a string parameter and return double
            // so now we get the result of add() method. now we need to display
            // the result in our displayField.
            // our value is in double. so we need to make it String type. So
            // here we called String.valueOf() method which is a static method
            // of String class.
            // it takes double parameter and returns String.
            // lastly we display the result in the display area by calling
            // setText() method from the JTextField class.

            // we have done the same things for the rest of the operation

            if (pluz) {
                displayField.setText(String.valueOf((calLogic.add(calLogic
                        .stringToDouble(firstValue), calLogic
                        .stringToDouble(Secondvalue)))));
            } else if (subs) {
                displayField.setText(String.valueOf((calLogic.substruct(
                        calLogic.stringToDouble(firstValue), calLogic
                                .stringToDouble(Secondvalue)))));
            } else if (divide) {
                displayField.setText(String.valueOf((calLogic.divide(calLogic
                        .stringToDouble(firstValue), calLogic
                        .stringToDouble(Secondvalue)))));
            } else if (multiply) {
                displayField.setText(String.valueOf((calLogic.multiply(calLogic
                        .stringToDouble(firstValue), calLogic
                        .stringToDouble(Secondvalue)))));
            }
        } else if (e.getActionCommand().endsWith("Clear")) {
            // if clear button press, it clears the displayFields
            displayField.setText("");
        }
    }

    // ==================================================================//
    /*****************************************************************
    * **********main method**************************************** *
    *****************************************************************/
    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        // here we use the system look and feel.. as Im in ubuntu 10.04, I get
        // its look and feel
        // if you are in windows, you we'll get the windows look and feel
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        Calc calcGui = new Calc();// Finally we instantiate the CalcGui
        // class/
        calcGui.setSize(300, 300); // here we define the size of our frame.
        calcGui.setVisible(true); // here we make the interface visible
        calcGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // set default
        // close
        // operation
        // ....
        calcGui.setResizable(false); // setResizable(false) is used so that, our
        // gui can't be resizable
    }
}